; ************************************************ ; New font routine for Feda: The Emblem of Justice ; ; Assumptions: ; font is 16x16 2bpp and @ $C40A92 ; background masks are @ $C02CDA (offsets at $C02CBA) ; ; ************************************************ #filename "feda.smc" #offset $0200 code feda_vwf { %position $2908 ; Get font offset PHP REP #$30 STY $00 AND #$00FF CLC ADC $00 STA $0C ; letter index?? LDA #$0040 ; #$0040 = size of letter STA $10 JSL $C015E0 ; multiplies $0C and $10 and stores result into $14 ; ************************************************ ; Set VRAM pointer ; ; Pre: font offset is in $14 ; Post: $0484 = VRAM pointer ; X and Y dont matter ; ************************************************ SEP #$20 LDA $0482 ; Y Tile Pos label1: CMP $0560 BCC label2 SBC $0560 BRA label1 label2: REP #$20 AND #$00FF XBA ASL PHA ; Push Y * #$0200 LDA $0480 AND #$FFF8 ; X Tile Pos * #$0008 CLC ADC $01,s ADC #$3000 STA $0484 ; $0484 = Y*#$0200 + X*#$0008 + #$3000 PLA ; ************************************************ ; Copy tiles from VRAM ; ; Pre: VRAM pointer has been set ; Post: VRAM data copied to $0488 ; ************************************************ label3: LDA $0484 ; set position to read from STA $2116 SEP #$20 LDA $213A ; read from VRAM to initialize auto-increment REP #$20 LDX #$0000 label4: LDA $2139 ; read a word from VRAM STA $0488,X ; store to upper tile INX INX CPX #$0010 ; check whether tile has been fully copied BNE label4 LDA $0484 CLC ADC #$0100 ; set position to read from STA $2116 SEP #$20 LDA $213A ; read from VRAM to initialize auto-increment REP #$20 LDX #$0000 label5: LDA $2139 ; read a word from VRAM and store STA $04B8,X ; store to lower tile INX INX CPX #$0010 ; check whether tile has been fully copied BNE label5 ; ************************************************ ; Main loop ; ; Pre: Y = font offset, X = memory offset, tiles shifted ; Post: shifted tiles have been placed into memory ; X and Y DO matter ; ************************************************ label6: LDX $14 ; Load font offset LDY #$0000 ; Read a line and store into $04EA-$04F1 label7: SEP #$20 LDA $C40A92,X ; left side, plane 0 STA $04EB STZ $04EA LDA $C40A93,X ; left side, plane 1 STA $04ED STZ $04EC LDA $C40AA2,X ; right side, plane 0 STA $04EF STZ $04EE LDA $C40AA3,X ; right side, plane 1 STA $04F1 STZ $04F0 ; get shift amount REP #$20 LDA $0480 AND #$0007 ; A = $0480 mod 8 ; shift line over label8: BEQ label9 ; end when shift amount = 0 LSR $04EA LSR $04EC LSR $04EE ; shift em LSR $04F0 DEC ; decrease shift amount BRA label8 ; loop back label9: SEP #$20 ; Draw left side (OR with old tiles) LDA $04EB ORA $04ED EOR #$FF PHA AND $0488,Y ORA $04EB STA $0488,Y PLA AND $0489,Y ORA $04ED STA $0489,Y ; Draw middle LDA $04EA ORA $04EF STA $0498,Y LDA $04EC ORA $04F1 STA $0499,Y ; Draw right side LDA $04EE STA $04A8,Y LDA $04F0 STA $04A9,Y ; end of loop -> (test loop conditon) INX INX INY INY CPY #$0010 BEQ labelA ; jump to some code if we have just finished the top tiles CPY #$0040 BEQ labelB ; jump to end of loop if we have just finished the bottom tiles BRL label7 ; else, go back to top of loop ; move to bottom tiles and start loop again labelA: REP #$20 TYA CLC ADC #$0020 ; move memory offset by + #$0020 (jump two tiles, mid and right) TAY TXA CLC ADC #$0010 ; move font offset by + #$0010 (jump one tile, right) TAX BRL label7 ; ************************************************ ; Fill in background mask ; ; Pre: letter is in memory, 8 bit A ; Post: background has been placed over ALL tiles ; X and Y don't matter, "old" tile had correct background ; ************************************************ labelB: REP #$20 LDA $0550 ; Background mask # (I think...) AND #$0007 ASL ; Multiply by two, to get the pointer TAX LDA $C02CBA,X STA $00 ; $00 = mask offset SEP #$20 LDY #$0000 ; Y = line count labelC: LDX $00 ; Set X to the mask offset labelD: LDA $0488,Y ORA $0489,Y EOR #$FF ; get a reverse mask of the line AND $C02CDA,X ; AND it with the background mask PHA ; push the mask onto the stack ORA $0488,Y STA $0488,Y ; apply to plane 0 PLA ORA $0489,Y STA $0489,Y ; apply to plane 1 INX INY INY ; move to next line TYA AND #$0F BEQ labelE ; if a tile is done, jump BRA labelD ; else return to top of loop labelE: CPY #$0060 BNE labelC ; if not the end of the tile, reset X and go to top of loop ; ************************************************ ; clean up ; ************************************************ ; Move X Pos LDA $0C ; load letter index TAX ;LDA $000000,X ; get width from width table LDA #$0C CLC ADC $0480 ; add to current x pos STA $0480 ; store LDA #$20 TSB $28 PLP RTS ; ************************************************ ; Modify the VRAM routine ; ************************************************ %position $28CE ; change size to copy %data $30 %position $28F8 %data $30 %position $28C2 ; change source pointer LDA #$0488 %position $28E8 LDA #$0488 }